/*
 *------------------------------------------------------------------------------
 * @File      :    os05a20_mipi.c
 * @Date      :    2021-07-06
 * @Author    :    lomboswer <lomboswer@lombotech.com>
 * @Brief     :    Source file for MDP(Media Development Platform).
 *
 * Copyright (C) 2020-2021, LomboTech Co.Ltd. All rights reserved.
 *------------------------------------------------------------------------------
 */
#include "ei_comm_camera.h"
#include "camera_usr.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */

#define SNS_ID 0520
#define SNS_NAME  "os05a20_mipi"
#define DEV_TYPE MCSI
static VISS_DEV gaVissDev[ISP_MAX_DEV_NUM] = {-1};
static SNS_STATE_S g_sastSns[VISS_MAX_DEV_NUM];

/* 2688x1944 4lane MIPI1500Mbps HDRVC10 30fps */
static const SNS_REG_S s_aRaw2688X1944p4lane30fps10bitlinear[] = {
    {0x0100, 0x00},
    {0x0103, 0x01},
    {0x0303, 0x01},
    {0x0305, 0x44},
    {0x0306, 0x00},
    {0x0307, 0x00},
    {0x0308, 0x03},
    {0x0309, 0x04},
    {0x030c, 0x01},
    {0x0322, 0x01},
    {0x032a, 0x00},
    {0x031e, 0x09},
    {0x0325, 0x48},
    {0x0328, 0x07},
    {0x300d, 0x11},
    {0x300e, 0x11},
    {0x300f, 0x11},
    {0x3026, 0x00},
    {0x3027, 0x00},
    {0x3010, 0x01},
    {0x3012, 0x41},
    {0x3016, 0xf0},
    {0x3018, 0xf0},
    {0x3028, 0xf0},
    {0x301e, 0x98},
    {0x3010, 0x01},
    {0x3011, 0x04},
    {0x3031, 0xa9},
    {0x3103, 0x48},
    {0x3104, 0x01},
    {0x3106, 0x10},
    {0x3400, 0x04},
    {0x3025, 0x03},
    {0x3425, 0x01},
    {0x3428, 0x01},
    {0x3406, 0x08},
    {0x3408, 0x03},
    {0x3501, 0x09},
    {0x3502, 0xa0},
    {0x3505, 0x83},
    {0x3508, 0x00},
    {0x3509, 0x80},
    {0x350a, 0x04},
    {0x350b, 0x00},
    {0x350c, 0x00},
    {0x350d, 0x80},
    {0x350e, 0x04},
    {0x350f, 0x00},
    {0x3600, 0x00},
    {0x3626, 0xff},
    {0x3605, 0x50},
    {0x3609, 0xb5},
    {0x3610, 0x69},
    {0x360c, 0x01},
    {0x3628, 0xa4},
    {0x3629, 0x6a},
    {0x362d, 0x10},
    {0x3660, 0x43},
    {0x3661, 0x06},
    {0x3662, 0x00},
    {0x3663, 0x28},
    {0x3664, 0x0d},
    {0x366a, 0x38},
    {0x366b, 0xa0},
    {0x366d, 0x00},
    {0x366e, 0x00},
    {0x3680, 0x00},
    {0x36c0, 0x00},
    {0x3621, 0x81},
    {0x3634, 0x31},
    {0x3620, 0x00},
    {0x3622, 0x00},
    {0x362a, 0xd0},
    {0x362e, 0x8c},
    {0x362f, 0x98},
    {0x3630, 0xb0},
    {0x3631, 0xd7},
    {0x3701, 0x0f},
    {0x3737, 0x02},
    {0x3740, 0x18},
    {0x3741, 0x04},
    {0x373c, 0x0f},
    {0x373b, 0x02},
    {0x3705, 0x00},
    {0x3706, 0x50},
    {0x370a, 0x00},
    {0x370b, 0xe4},
    {0x3709, 0x4a},
    {0x3714, 0x21},
    {0x371c, 0x00},
    {0x371d, 0x08},
    {0x375e, 0x0e},
    {0x3760, 0x13},
    {0x3776, 0x10},
    {0x3781, 0x02},
    {0x3782, 0x04},
    {0x3783, 0x02},
    {0x3784, 0x08},
    {0x3785, 0x08},
    {0x3788, 0x01},
    {0x3789, 0x01},
    {0x3797, 0x04},
    {0x3798, 0x01},
    {0x3799, 0x00},
    {0x3761, 0x02},
    {0x3762, 0x0d},
    {0x3800, 0x00},
    {0x3801, 0x00},
    {0x3802, 0x00},
    {0x3803, 0x0c},
    {0x3804, 0x0e},
    {0x3805, 0xff},
    {0x3806, 0x08},
    {0x3807, 0x6f},
    {0x3808, 0x0a},
    {0x3809, 0x80},
    {0x380a, 0x07},
    {0x380b, 0x98},
    {0x380c, 0x02},
    {0x380d, 0xd0},
    {0x380e, 0x09},
    {0x380f, 0xc0},
    {0x3811, 0x10},
    {0x3813, 0x04},
    {0x3814, 0x01},
    {0x3815, 0x01},
    {0x3816, 0x01},
    {0x3817, 0x01},
    {0x381c, 0x00},
    {0x3820, 0x00},
    {0x3821, 0x04},
    {0x3822, 0x54},
    {0x3823, 0x18},
    {0x3826, 0x00},
    {0x3827, 0x01},
    {0x3833, 0x00},
    {0x3832, 0x02},
    {0x383c, 0x48},
    {0x383d, 0xff},
    {0x3843, 0x20},
    {0x382d, 0x08},
    {0x3d85, 0x0b},
    {0x3d84, 0x40},
    {0x3d8c, 0x63},
    {0x3d8d, 0x00},
    {0x4000, 0x78},
    {0x4001, 0x2b},
    {0x4004, 0x00},
    {0x4005, 0x40},
    {0x4028, 0x2f},
    {0x400a, 0x01},
    {0x4010, 0x12},
    {0x4008, 0x02},
    {0x4009, 0x0d},
    {0x401a, 0x58},
    {0x4050, 0x00},
    {0x4051, 0x01},
    {0x4052, 0x00},
    {0x4053, 0x80},
    {0x4054, 0x00},
    {0x4055, 0x80},
    {0x4056, 0x00},
    {0x4057, 0x80},
    {0x4058, 0x00},
    {0x4059, 0x80},
    {0x430b, 0xff},
    {0x430c, 0xff},
    {0x430d, 0x00},
    {0x430e, 0x00},
    {0x4501, 0x18},
    {0x4502, 0x00},
    {0x4643, 0x00},
    {0x4640, 0x01},
    {0x4641, 0x04},
    {0x480e, 0x00},
    {0x4813, 0x00},
    {0x4815, 0x2b},
    {0x486e, 0x36},
    {0x486f, 0x84},
    {0x4860, 0x00},
    {0x4861, 0xa0},
    {0x484b, 0x05},
    {0x4850, 0x00},
    {0x4851, 0xaa},
    {0x4852, 0xff},
    {0x4853, 0x8a},
    {0x4854, 0x08},
    {0x4855, 0x30},
    {0x4800, 0x60},
    {0x4837, 0x1d},
    {0x484a, 0x3f},
    {0x5000, 0xc9},
    {0x5001, 0x43},
    {0x5002, 0x00},
    {0x5211, 0x03},
    {0x5291, 0x03},
    {0x520d, 0x0f},
    {0x520e, 0xfd},
    {0x520f, 0xa5},
    {0x5210, 0xa5},
    {0x528d, 0x0f},
    {0x528e, 0xfd},
    {0x528f, 0xa5},
    {0x5290, 0xa5},
    {0x5004, 0x40},
    {0x5005, 0x00},
    {0x5180, 0x00},
    {0x5181, 0x10},
    {0x5182, 0x0f},
    {0x5183, 0xff},
    {0x580b, 0x03},
    {0x4d00, 0x03},
    {0x4d01, 0xe9},
    {0x4d02, 0xba},
    {0x4d03, 0x66},
    {0x4d04, 0x46},
    {0x4d05, 0xa5},
    {0x3603, 0x3c},
    {0x3703, 0x26},
    {0x3709, 0x49},
    {0x3708, 0x2d},
    {0x3719, 0x1c},
    {0x371a, 0x06},
    {0x4000, 0x79},
    {0x4837, 0x1d},
    {0x0100, 0x01},
    {0x0100, 0x01},
    {0x0100, 0x01},
    {0x0100, 0x01},
};

/* 2688x1944 4lane MIPI1500Mbps HDRVC10 30fps */
static const SNS_REG_S s_aRaw2688X1944p4lane30fps10bit2to1[] = {
{0x4600,0x01},
{0x4601,0x04},
{0x4603,0x00},
{0x0103,0x01},
{0x0303,0x01},
{0x0305,0x5e},
{0x0306,0x00},
{0x0307,0x00},
{0x0308,0x03},
{0x0309,0x04},
{0x032a,0x00},
{0x031e,0x09},
{0x0325,0x48},
{0x0328,0x07},
{0x300d,0x11},
{0x300e,0x11},
{0x300f,0x11},
{0x3010,0x01},
{0x3012,0x41},
{0x3016,0xf0},
{0x3018,0xf0},
{0x3028,0xf0},
{0x301e,0x98},
{0x3010,0x04},
{0x3011,0x06},
{0x3031,0xa9},
{0x3103,0x48},
{0x3104,0x01},
{0x3106,0x10},
{0x3501,0x09},
{0x3502,0xa0},
{0x3505,0x83},
{0x3508,0x00},
{0x3509,0x80},
{0x350a,0x04},
{0x350b,0x00},
{0x350c,0x00},
{0x350d,0x80},
{0x350e,0x04},
{0x350f,0x00},
{0x3600,0x00},
{0x3626,0xff},
{0x3605,0x50},
{0x3609,0xb5},
{0x3610,0x69},
{0x360c,0x01},
{0x3628,0xa4},
{0x3629,0x6a},
{0x362d,0x10},
{0x3660,0x42},
{0x3661,0x07},
{0x3662,0x00},
{0x3663,0x28},
{0x3664,0x0d},
{0x366a,0x38},
{0x366b,0xa0},
{0x366d,0x00},
{0x366e,0x00},
{0x3680,0x00},
{0x36c0,0x00},
{0x3621,0x81},
{0x3634,0x31},
{0x3620,0x00},
{0x3622,0x00},
{0x362a,0xd0},
{0x362e,0x8c},
{0x362f,0x98},
{0x3630,0xb0},
{0x3631,0xd7},
{0x3701,0x0f},
{0x3737,0x02},
{0x3741,0x04},
{0x373c,0x0f},
{0x373b,0x02},
{0x3705,0x00},
{0x3706,0x50},
{0x370a,0x00},
{0x370b,0xe4},
{0x3709,0x4a},
{0x3714,0x21},
{0x371c,0x00},
{0x371d,0x08},
{0x375e,0x0e},
{0x3760,0x13},
{0x3776,0x10},
{0x3781,0x02},
{0x3782,0x04},
{0x3783,0x02},
{0x3784,0x08},
{0x3785,0x08},
{0x3788,0x01},
{0x3789,0x01},
{0x3797,0x84},
{0x3798,0x01},
{0x3799,0x00},
{0x3761,0x02},
{0x3762,0x0d},
{0x3800,0x00},
{0x3801,0x00},
{0x3802,0x00},
{0x3803,0x0c},
{0x3804,0x0e},
{0x3805,0xff},
{0x3806,0x08},
{0x3807,0x6f},
{0x3808,0x0a},
{0x3809,0x80},
{0x380a,0x07},
{0x380b,0x98},
{0x380c,0x02},
{0x380d,0xd0},
{0x380e,0x09},
{0x380f,0xc0},
{0x3813,0x04},
{0x3814,0x01},
{0x3815,0x01},
{0x3816,0x01},
{0x3817,0x01},
{0x381c,0x08},
{0x3820,0x00},
{0x3821,0x24},
{0x3823,0x08},
{0x3826,0x00},
{0x3827,0x01},
{0x3832,0x02},
{0x3833,0x01},
{0x383c,0x48},
{0x383d,0xff},
{0x3843,0x20},
{0x382d,0x08},
{0x3d85,0x0b},
{0x3d84,0x40},
{0x3d8c,0x63},
{0x3d8d,0x00},
{0x4000,0x78},
{0x4001,0x2b},
{0x4005,0x40},
{0x4028,0x2f},
{0x400a,0x01},
{0x4010,0x12},
{0x4008,0x02},
{0x4009,0x0d},
{0x401a,0x58},
{0x4050,0x00},
{0x4051,0x01},
{0x4052,0x00},
{0x4053,0x80},
{0x4054,0x00},
{0x4055,0x80},
{0x4056,0x00},
{0x4057,0x80},
{0x4058,0x00},
{0x4059,0x80},
{0x430b,0xff},
{0x430c,0xff},
{0x430d,0x00},
{0x430e,0x00},
{0x4501,0x18},
{0x4502,0x00},
{0x4643,0x00},
{0x4640,0x01},
{0x4641,0x04},
{0x480e,0x04},
{0x4813,0x98},
{0x4815,0x2b},
{0x486e,0x36},
{0x486f,0x84},
{0x4860,0x00},
{0x4861,0xa0},
{0x484b,0x05},
{0x4850,0x00},
{0x4851,0xaa},
{0x4852,0xff},
{0x4853,0x8a},
{0x4854,0x08},
{0x4855,0x30},
{0x4800,0x00},
{0x4837,0x0a},
{0x484a,0x3f},
{0x5000,0xc9},
{0x5001,0x43},
{0x5002,0x00},
{0x5211,0x03},
{0x5291,0x03},
{0x520d,0x0f},
{0x520e,0xfd},
{0x520f,0xa5},
{0x5210,0xa5},
{0x528d,0x0f},
{0x528e,0xfd},
{0x528f,0xa5},
{0x5290,0xa5},
{0x5004,0x40},
{0x5005,0x00},
{0x5180,0x00},
{0x5181,0x10},
{0x5182,0x0f},
{0x5183,0xff},
{0x580b,0x03},
{0x4d00,0x03},
{0x4d01,0xe9},
{0x4d02,0xba},
{0x4d03,0x66},
{0x4d04,0x46},
{0x4d05,0xa5},
{0x3603,0x3c},
{0x3703,0x26},
{0x3709,0x49},
{0x3708,0x2d},
{0x3719,0x1c},
{0x371a,0x06},
{0x4000,0x79},
{0x380c,0x02},
{0x380d,0xd0},
{0x380e,0x09},
{0x380f,0xc0},
{0x3501,0x08},
{0x3502,0xbb},
{0x3511,0x00},
{0x3512,0x20},
{0x0100,0x01},
{0x0100,0x01},
{0x0100,0x01},
{0x0100,0x01},
};

static CAMERA_POWER_ACT_S s_stPowerUpAct[] = {
    {SNS_RESET, SNS_DOWN},
    {SNS_DELAY, 20},
    {SNS_PWDN, SNS_DOWN},
    {SNS_DELAY, 20},
    {SNS_PWDN, SNS_UP},
    {SNS_DELAY, 20},
    {SNS_RESET,  SNS_UP},
    {SNS_DELAY, 5},
};

static CAMERA_POWER_ACT_S s_sPowerDownAct[] = {
    {SNS_RESET, SNS_DOWN},
    {SNS_DELAY, 10},
    {SNS_PWDN,  SNS_DOWN},
};
/*vts:0x380e,0x380f
 *hts:0x380c,0x380d
 */
static SNS_TYPE_ATTR_S s_astSnsAttr[] = {
	{
        .enSnsType                  = OS05A20_MIPI_2688_1944_25FPS_RAW10,
        .enPixelFormat              = PIX_FMT_RGB_BAYER_10BITS,
        .enRgbSeq                   = VISS_RGB_SEQ_BGGR,
        .stSize                     = {2688, 1944},
        .u32ModuleClk               = 297000000,
        .u32Mclock                  = 24000000,
        .enWorkMode                 = VISS_WORK_MODE_1Chn,
        .enWdrMode                  = VISS_WDR_MODE_VC,

        .u32IspClk                  = 216000000,
        .u32IppuClk                 = 432000000,
        .u32Pclk                    = 53913600,
        .u32Vts                     = 0x0bb3,/* 2995 */
        .u32Hts                     = 0x02D0,/* 720 */
        .enIspWdrMode               = WDR_MODE_NONE,

        .u32FrameRate                = 25,
        .astRegCfgs[0].pstRegs      = s_aRaw2688X1944p4lane30fps10bitlinear,
        .astRegCfgs[0].u32RegsCnt   = ARRAY_SIZE(s_aRaw2688X1944p4lane30fps10bitlinear),

        .stDevCfg.stMcsiCfg.u32PhyFreq  = 544000000,
        .stDevCfg.stMcsiCfg.enDlanes    = VISS_LANE_NUM_4Lane,
    },
    {
        .enSnsType                  = OS05A20_MIPI_2688_1944_30FPS_RAW10,
        .enPixelFormat              = PIX_FMT_RGB_BAYER_10BITS,
        .enRgbSeq                   = VISS_RGB_SEQ_BGGR,
        .stSize                     = {2688, 1944},
        .u32ModuleClk               = 297000000,
        .u32Mclock                  = 24000000,
        .enWorkMode                 = VISS_WORK_MODE_1Chn,
        .enWdrMode                  = VISS_WDR_MODE_VC,

        .u32IspClk                  = 216000000,
        .u32IppuClk                 = 432000000,
        .u32Pclk                    = 53913600,
        .u32Vts                     = 0x09c0,/* 2496 */
        .u32Hts                     = 0x02D0,/* 720 */
        .enIspWdrMode               = WDR_MODE_NONE,

        .u32FrameRate                = 30,
        .astRegCfgs[0].pstRegs      = s_aRaw2688X1944p4lane30fps10bitlinear,
        .astRegCfgs[0].u32RegsCnt   = ARRAY_SIZE(s_aRaw2688X1944p4lane30fps10bitlinear),

        .stDevCfg.stMcsiCfg.u32PhyFreq  = 544000000,
        .stDevCfg.stMcsiCfg.enDlanes    = VISS_LANE_NUM_4Lane,
    },

    {
        .enSnsType                  = OS05A20_MIPI_2688_1944_2TO1_25FPS_RAW10,
        .enPixelFormat              = PIX_FMT_RGB_BAYER_10BITS,
        .enRgbSeq                   = VISS_RGB_SEQ_BGGR,
        .stSize                     = {2688, 1944},
        .u32ModuleClk               = 594000000,
        .u32Mclock                  = 24000000,
        .enWorkMode                 = VISS_WORK_MODE_2Chn,
        .enWdrMode                  = VISS_WDR_MODE_VC,

        .u32IspClk                  = 264000000,
        .u32IppuClk                 = 528000000,
        .u32Pclk                    = 107827200,
        .u32Vts                     = 0x0bb3,/* 2995 */
        .u32Hts                     = 0x02D0,/* 720 */
        .enIspWdrMode               = WDR_MODE_2TO1_FRAME,

        .u32FrameRate                = 25,
        .astRegCfgs[0].pstRegs      = s_aRaw2688X1944p4lane30fps10bit2to1,
        .astRegCfgs[0].u32RegsCnt   = ARRAY_SIZE(s_aRaw2688X1944p4lane30fps10bit2to1),

        .stDevCfg.stMcsiCfg.u32PhyFreq  = 1500000000,
        .stDevCfg.stMcsiCfg.enDlanes    = VISS_LANE_NUM_4Lane,
    },
    {
        .enSnsType                  = OS05A20_MIPI_2688_1944_2TO1_30FPS_RAW10,
        .enPixelFormat              = PIX_FMT_RGB_BAYER_10BITS,
        .enRgbSeq                   = VISS_RGB_SEQ_BGGR,
        .stSize                     = {2688, 1944},
        .u32ModuleClk               = 594000000,
        .u32Mclock                  = 24000000,
        .enWorkMode                 = VISS_WORK_MODE_2Chn,
        .enWdrMode                  = VISS_WDR_MODE_VC,

        .u32IspClk                  = 264000000,
        .u32IppuClk                 = 528000000,
        .u32Pclk                    = 107827200,
        .u32Vts                     = 0x09C0,/* 2496 */
        .u32Hts                     = 0x02D0,/* 720 */
        .enIspWdrMode               = WDR_MODE_2TO1_FRAME,

        .u32FrameRate               = 30,
        .astRegCfgs[0].pstRegs      = s_aRaw2688X1944p4lane30fps10bit2to1,
        .astRegCfgs[0].u32RegsCnt   = ARRAY_SIZE(s_aRaw2688X1944p4lane30fps10bit2to1),

        .stDevCfg.stMcsiCfg.u32PhyFreq  = 1500000000,
        .stDevCfg.stMcsiCfg.enDlanes    = VISS_LANE_NUM_4Lane,
    },
};

static int CAMERA_SetI2cInfo(VISS_DEV dev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    if (pstSnsState->stI2cInfo.fd > 0) {
        return EI_SUCCESS;
    }

    pstSnsState->stI2cInfo.u8RegBits = 16;
    pstSnsState->stI2cInfo.u8ValBits = 8;
    pstSnsState->stI2cInfo.u16I2cBusNum = 4;
    pstSnsState->stI2cInfo.u16I2cDevAddr = 0x36;
    pstSnsState->pcName = SNS_NAME;

    return EI_SUCCESS;
}
static EI_S32 CAMERA_Detect(VISS_DEV VissDev)
{
    EI_U8 u8Tmp[3];
    EI_S32 s32Ret = EI_SUCCESS;
    EI_U32 u32Id;
    SNS_STATE_S *pstSnsState = EI_NULL;
    I2C_INFO_S *pstI2cInfo = EI_NULL;

    SNS_GET_CTX(VissDev, pstSnsState);

    pstI2cInfo = &pstSnsState->stI2cInfo;

    CAMERA_CHECK_POINTER(pstI2cInfo->pfnReadReg);
    s32Ret = pstI2cInfo->pfnReadReg(pstSnsState, 0x300A, &u8Tmp[0]);
    if (s32Ret != 0) {
        PRT_VISS_ERR("%s tmp[0]=%x\n", SNS_NAME, u8Tmp[0]);
        return s32Ret;
    }
    s32Ret = pstI2cInfo->pfnReadReg(pstSnsState, 0x300B, &u8Tmp[1]);
    if (s32Ret != 0) {
        PRT_VISS_ERR("%s tmp[0]=%x,tmp[1]=%x\n", SNS_NAME, u8Tmp[0], u8Tmp[1]);
        return s32Ret;
    }
    s32Ret = pstI2cInfo->pfnReadReg(pstSnsState, 0x300C, &u8Tmp[2]);
    if (s32Ret != 0) {
        PRT_VISS_ERR("%s tmp[0]=%x,tmp[1]=%x,tmp[2]=%x\n", SNS_NAME, u8Tmp[0], u8Tmp[1],u8Tmp[2]);
        return s32Ret;
    }
    u32Id = (u8Tmp[0] << 16) | u8Tmp[1] << 8 | u8Tmp[2];

    if (u32Id != 0x530541) {
        PRT_VISS_ERR("%s ID wrong! (0x%06x != 0x530541)\n", SNS_NAME, u32Id);
        return EI_FAILURE;
    }

    return EI_SUCCESS;
}

static EI_S32 CAMERA_Stream(VISS_DEV dev, EI_BOOL bOn)
{
    SNS_STATE_S *pstSnsState = EI_NULL;
    EI_S32 s32Ret = EI_SUCCESS;
    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);
    PRT_VISS_INFO("%s ----CAMERA_Stream----%d\n", SNS_NAME, bOn);

    if (bOn) {
        s32Ret = pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x0100, 0x01);
        if (s32Ret != EI_SUCCESS) {
            PRT_VISS_ERR("CAMERA_Stream err*******%d\n", bOn);
        }
    } else {
        s32Ret = pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x0100, 0x00);
        if (s32Ret != EI_SUCCESS) {
            PRT_VISS_ERR("CAMERA_Stream err*******%d\n", bOn);
        }
    }
    return s32Ret;

}

/* The following functions can be modified as needed */

static int CAMERA_I2cInit(VISS_DEV dev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;
    int ret = EI_SUCCESS;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    ret = CAMERA_SetI2cInfo(dev);
    CAMERA_CHECK_SUCCESS(ret);

    ret = CAMERA_I2C_Reg_Ops(&pstSnsState->stI2cInfo);
    CAMERA_CHECK_SUCCESS(ret);

    return EI_SUCCESS;
}

static int CAMERA_I2cExit(VISS_DEV dev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    return CAMERA_ExitI2c(pstSnsState);
}

static EI_S32 CAMERA_PowerUp(VISS_DEV VissDev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(VissDev, pstSnsState);

    CAMERA_SensorPowerUp(VissDev, pstSnsState);

    return 0;
}

static EI_S32 CAMERA_PowerDown(VISS_DEV VissDev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(VissDev, pstSnsState);

    CAMERA_SensorPowerDown(VissDev, pstSnsState);

    return 0;
}

static EI_S32 CAMERA_SetGain(ISP_DEV dev, EI_FLOAT fGain);
static EI_S32 CAMERA_SetExpTime(ISP_DEV dev, EI_FLOAT *afIntTime);

static EI_S32 CAMERA_Init(VISS_DEV dev)
{
    EI_U32 j;
    const SNS_TYPE_ATTR_S *pstSnsType;
    SNS_STATE_S *pstSnsState = EI_NULL;
    EI_S32 s32Ret;
    I2C_INFO_S *pstI2cInfo = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    pstI2cInfo = &pstSnsState->stI2cInfo;

    pstSnsType = pstSnsState->pstSnsAttr;
    for (j = 0; j < MAX_COF; j++) {
        s32Ret = pstSnsState->stI2cInfo.pfnwriteRegList(pstSnsState,
                pstSnsType->astRegCfgs[j].pstRegs, pstSnsType->astRegCfgs[j].u32RegsCnt);
        if (s32Ret != EI_SUCCESS) {
            PRT_VISS_ERR("%s writeRegList err\n", SNS_NAME);
            return s32Ret;
        }
    }

	if(pstSnsType->enSnsType == OS05A20_MIPI_2688_1944_25FPS_RAW10) {
        s32Ret += pstI2cInfo->pfnWriteReg(pstSnsState, 0x380e, 0x0b);
        s32Ret += pstI2cInfo->pfnWriteReg(pstSnsState, 0x380f, 0xb3);
        if (s32Ret != 0) {
            PRT_VISS_ERR("CAMERA_Init error\n");
            return s32Ret;
        }
    }

    if(pstSnsType->enSnsType == OS05A20_MIPI_2688_1944_2TO1_25FPS_RAW10) {
        s32Ret += pstI2cInfo->pfnWriteReg(pstSnsState, 0x380e, 0x0b);
        s32Ret += pstI2cInfo->pfnWriteReg(pstSnsState, 0x380f, 0xb3);
        if (s32Ret != 0) {
            PRT_VISS_ERR("CAMERA_Init error\n");
            return s32Ret;
        }
    }

    if ((pstSnsState->afIntTime[0] > 0.000001) && (pstSnsState->fGain >= 1.0)) {
        CAMERA_SetExpTime(pstSnsState->IspDev, pstSnsState->afIntTime);
        CAMERA_SetGain(pstSnsState->IspDev, pstSnsState->fGain);
    }

    PRT_VISS_INFO("%s writeRegList success\n", SNS_NAME);

    return s32Ret;
}

static void CAMERA_Exit(VISS_DEV dev)
{
    CAMERA_I2cExit(dev);

    return;
}

static EI_S32 CAMERA_SetImageMode(VISS_DEV dev, SNS_TYPE_E enSnsType)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    pstSnsState->enSnsType = enSnsType;
    pstSnsState->bSyncInit = EI_FALSE;

    return EI_SUCCESS;
}

static EI_S32 CAMERA_EnumSnstype(VISS_DEV VissDev, EI_U32 u32Index, SNS_TYPE_E *peSnstype)
{
    const SNS_TYPE_ATTR_S *pstSnsType;

    if (u32Index >= ARRAY_SIZE(s_astSnsAttr))
        return EN_ERR_NO_FOUND;

    pstSnsType = &s_astSnsAttr[u32Index];

    *peSnstype = pstSnsType->enSnsType;

    return EI_SUCCESS;
}

static EI_S32 CAMERA_SetFrameRate(VISS_DEV VissDev, EI_FLOAT f32Fps)
{
    I2C_INFO_S *pstI2cInfo = EI_NULL;
    SNS_STATE_S *pstSnsState = EI_NULL;
    EI_S32 s32Ret = EI_SUCCESS;
    EI_U32 u32Pclk, u32Hts, u32Vts;

    SNS_GET_CTX(VissDev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    pstI2cInfo = &pstSnsState->stI2cInfo;
    u32Pclk = pstSnsState->pstSnsAttr->u32Pclk;
    u32Hts = pstSnsState->pstSnsAttr->u32Hts;

    if (pstSnsState->pstSnsAttr->enIspWdrMode == WDR_MODE_NONE) {
        if (pstSnsState->pstSnsAttr->u32FrameRate < f32Fps || 1 > f32Fps) {
            cprintf("1 <= set fps <= %d, set fps: %f\n", pstSnsState->pstSnsAttr->u32FrameRate, f32Fps);
            f32Fps = pstSnsState->pstSnsAttr->u32FrameRate;
        }

        u32Vts = u32Pclk / u32Hts / f32Fps;
    } else if (pstSnsState->pstSnsAttr->enIspWdrMode == WDR_MODE_2TO1_FRAME) {
        if (pstSnsState->pstSnsAttr->u32FrameRate < f32Fps || 1 > f32Fps) {
            cprintf("1 <= set fps <= %d, set fps: %f\n", pstSnsState->pstSnsAttr->u32FrameRate, f32Fps);
            f32Fps = pstSnsState->pstSnsAttr->u32FrameRate;
        }

        u32Vts = u32Pclk / 2 / u32Hts / f32Fps;
    } else {
        return EN_ERR_NOT_SUPPORT;
    }

    s32Ret += pstI2cInfo->pfnWriteReg(pstSnsState, 0x380e, u32Vts >> 8);
    s32Ret += pstI2cInfo->pfnWriteReg(pstSnsState, 0x380f, u32Vts);
    if (s32Ret != 0) {
        cprintf("CAMERA_Init error\n");
        return s32Ret;
    }

    pstSnsState->pstSnsAttr->u32Vts = u32Vts;

    return EI_SUCCESS;
}

static EI_S32 CAMERA_InitSensorExpFunction(SENSOR_EXP_FUNC_S *pstSensorExpFunc)
{
    CAMERA_CHECK_POINTER(pstSensorExpFunc);

    memset(pstSensorExpFunc, 0, sizeof(SENSOR_EXP_FUNC_S));

    pstSensorExpFunc->pfnSensorPowerUp  = CAMERA_PowerUp;
    pstSensorExpFunc->pfnSensorPowerDown = CAMERA_PowerDown;
    pstSensorExpFunc->pfnSensorDetect   = CAMERA_Detect;
    pstSensorExpFunc->pfnSensorInit     = CAMERA_Init;
    pstSensorExpFunc->pfnSensorStream   = CAMERA_Stream;
    pstSensorExpFunc->pfnSensorExit     = CAMERA_Exit;
    pstSensorExpFunc->pfnSensorSetImageMode   = CAMERA_SetImageMode;
    pstSensorExpFunc->pfnSensorEnumSnstype   = CAMERA_EnumSnstype;
    pstSensorExpFunc->pfnSensorSetFrameRate   = CAMERA_SetFrameRate;

    return EI_SUCCESS;
}

static EI_S32 CAMERA_GetAeDefault(ISP_DEV dev, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
{
    CAMERA_CHECK_POINTER(pstAeSnsDft);

    return EI_SUCCESS;
}

static EI_S32 CAMERA_SetFps(ISP_DEV dev, EI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
{
    VISS_DEV Dev;

    SNS_GET_ISP_TO_VISS(dev, Dev);

    CAMERA_CHECK_POINTER(pstAeSnsDft);

    return CAMERA_SetFrameRate(Dev, f32Fps);
}

static EI_S32 CAMERA_SetExpTime(ISP_DEV dev, EI_FLOAT *afIntTime)
{
    SNS_STATE_S *pstSnsState = EI_NULL;
    EI_S32 s32Ret = EI_SUCCESS;
    EI_U32 u32Pclk, u32Hts, u32Vts;
    EI_U32 shutter_time;
    VISS_DEV Dev;
    EI_U32 exp_short_h, exp_short_l;
    EI_U32 exp_short;

    SNS_GET_ISP_TO_VISS(dev, Dev);

    SNS_GET_CTX(Dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);
    CAMERA_CHECK_POINTER(afIntTime);
    pstSnsState->afIntTime[0] = afIntTime[0];
    pstSnsState->afIntTime[1] = afIntTime[1];
    pstSnsState->afIntTime[2] = afIntTime[2];
    pstSnsState->afIntTime[3] = afIntTime[3];
    pstSnsState->IspDev = dev;
    CAMERA_CHECK_POWERON(pstSnsState);

    u32Pclk = pstSnsState->pstSnsAttr->u32Pclk;
    u32Hts = pstSnsState->pstSnsAttr->u32Hts;
    u32Vts = pstSnsState->pstSnsAttr->u32Vts;

    if ((u32Pclk == 0) || (u32Hts == 0) || (u32Vts == 0)) {
        PRT_VISS_ERR("error! u32Pclk %d, u32Hts %d, u32Vts %d\n", u32Pclk, u32Hts, u32Vts);
        return EI_FAILURE;
    }

    /* afIntTime[0] long/medium/short/vshort exptime (s) */
    shutter_time = afIntTime[0] * u32Pclk / u32Hts;

    if (shutter_time < 4)
        shutter_time = 4;

    if (shutter_time > (u32Vts - 8))
        shutter_time = (u32Vts - 8);

    //s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x380e, Vmax >> 8);
    //s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x380f, Vmax);

    s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3208, 0x00);

    s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3501, ((0xff00 & shutter_time) >> 8));
    s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3502, (0x00ff & shutter_time));

    if (pstSnsState->pstSnsAttr->enIspWdrMode == WDR_MODE_2TO1_FRAME) {
        exp_short = shutter_time / afIntTime[1];

        exp_short_h = (unsigned char)((0xff00 & exp_short) >> 8);
        exp_short_l = (unsigned char)((0x00ff & exp_short));

        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3511, exp_short_h);
        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3512, exp_short_l);
    }

    afIntTime[0] = (EI_FLOAT)(shutter_time) * u32Hts / u32Pclk;
    if (afIntTime[0] < 0.00001) {
        PRT_VISS_WARN("Warning! afIntTime[0] < 0.00001, now force 0.00001 \n");
        afIntTime[0] = 0.00001;
    }

    return s32Ret;
}

static EI_S32 CAMERA_SetGain(ISP_DEV dev, EI_FLOAT fGain)
{
    SNS_STATE_S *pstSnsState = EI_NULL;
    EI_S32 s32Ret = EI_SUCCESS;
    VISS_DEV Dev;
    EI_U32 gainlow = 0;
    EI_U32 gainhigh = 0;
    EI_U32 digi_gain;
    EI_U32 ana_gain;
    EI_U32 gain;

    SNS_GET_ISP_TO_VISS(dev, Dev);

    SNS_GET_CTX(Dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);
    pstSnsState->fGain = fGain;
    CAMERA_CHECK_POWERON(pstSnsState);

    gain = fGain * 16 * 8;

    if (gain <= (16 * 8))
        gain = 16 * 8;

    if (gain > (16 * 15 * 8)) {
        ana_gain = 16 * 15 * 8;
        digi_gain = gain * 1024 / ana_gain;
        gain = ana_gain;
    } else {
        digi_gain = 1024;
    }

    gainhigh = (unsigned char)((gain>>8)&0xff);
    gainlow = (unsigned char)(gain&0xff);

    s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3508, gainhigh);
    s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3509, gainlow);

    s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x350a, digi_gain >> 8);
    s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x350b, digi_gain & 0xff);

    if (pstSnsState->pstSnsAttr->enIspWdrMode == WDR_MODE_2TO1_FRAME) {
        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x350c, gainhigh);
        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x350d, gainlow);
        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x350e, digi_gain >> 8);
        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x350f, digi_gain & 0xff);
    }

    s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3208, 0x10);
    s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x3208, 0xa0);

    if (s32Ret != EI_SUCCESS) {
        PRT_VISS_ERR("\n");
    }

    return s32Ret;
}

static EI_S32 CAMERA_InitAeExpFunction(AE_SENSOR_EXP_FUNC_S *pstExpFuncs)
{
    CAMERA_CHECK_POINTER(pstExpFuncs);

    memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S));

    pstExpFuncs->pfnGetAeDefault    = CAMERA_GetAeDefault;
    pstExpFuncs->pfnSetFps          = CAMERA_SetFps;
    pstExpFuncs->pfnSetExpTime      = CAMERA_SetExpTime;
    pstExpFuncs->pfnSetGain         = CAMERA_SetGain;

    return EI_SUCCESS;
}

static EI_S32 CAMERA_GetAwbDefault(ISP_DEV dev, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft)
{
    CAMERA_CHECK_POINTER(pstAwbSnsDft);

    return EI_SUCCESS;
}

static EI_S32 CAMERA_InitAwbExpFunction(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs)
{
    CAMERA_CHECK_POINTER(pstExpFuncs);

    memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S));
    pstExpFuncs->pfnGetAwbDefault = CAMERA_GetAwbDefault;

    return EI_SUCCESS;
}

/****************************************************************************
 * callback structure                                                       *
 ****************************************************************************/

static EI_S32 CAMERA_CtxInit(VISS_DEV dev)
{
    SNS_STATE_S *pastSnsStateCtx = EI_NULL;

    SNS_GET_CTX(dev, pastSnsStateCtx);

    CAMERA_CHECK_POINTER(pastSnsStateCtx);

    memset(pastSnsStateCtx, 0, sizeof(SNS_STATE_S));

    pastSnsStateCtx->pstPowerUpAct      = s_stPowerUpAct;
    pastSnsStateCtx->pstPowerDownAct    = s_sPowerDownAct;
    pastSnsStateCtx->u8PwrUpActs        = ARRAY_SIZE(s_stPowerUpAct);
    pastSnsStateCtx->u8PwrDnActs        = ARRAY_SIZE(s_sPowerDownAct);

    return EI_SUCCESS;
}

static EI_VOID CAMERA_CtxExit(VISS_DEV dev)
{
    return ;
}

static EI_S32 CAMERA_RegisterVissCallback(VISS_DEV dev, SNS_TYPE_E enType)
{
    EI_S32 s32Ret;
    SENSOR_S stSns = {0};
    EI_U32 i;
    SNS_STATE_S *pstSnsState = EI_NULL;

    s32Ret = CAMERA_CtxInit(dev);
    if (EI_SUCCESS != s32Ret) {
        return EI_FAILURE;
    }

    SNS_GET_CTX(dev, pstSnsState);

    for (i = 0; i < ARRAY_SIZE(s_astSnsAttr); i++) {
        if (enType == s_astSnsAttr[i].enSnsType) {
            pstSnsState->pstSnsAttr = &s_astSnsAttr[i];
            break;
        }
    }

    pstSnsState->enSnsType = enType;
    pstSnsState->Dev = dev;

    if (i >= ARRAY_SIZE(s_astSnsAttr)) {
        PRT_VISS_ERR("%s does not support this chn configuration", SNS_NAME);
        return EI_FAILURE;
    }

    s32Ret = CAMERA_I2cInit(dev);
    if (EI_SUCCESS != s32Ret) {
        return EI_FAILURE;
    }

    stSns.stSnsAttrInfo.eSensorId = SNS_ID;
    stSns.stSnsAttrInfo.enDevType = DEV_TYPE;
    stSns.stSnsAttrInfo.pstSns = pstSnsState;

    s32Ret  = CAMERA_InitSensorExpFunction(&stSns.stSnsAttrInfo.stSnsExp);
    s32Ret |= VISS_SensorRegCallBack(dev, &stSns);
    if (EI_SUCCESS != s32Ret) {
        PRT_VISS_ERR("%s sensor register callback function failed!\n", SNS_NAME);
        return s32Ret;
    }

    s32Ret = CAMERA_OpenI2c(pstSnsState);
    CAMERA_CHECK_SUCCESS(s32Ret);

    return EI_SUCCESS;
}

static EI_S32 CAMERA_UnregisterVissCallback(VISS_DEV dev)
{
    EI_S32 s32Ret;

    s32Ret = VISS_SensorUnRegCallBack(dev, SNS_ID);
    if (EI_SUCCESS != s32Ret) {
        PRT_VISS_ERR("%s sensor unregister callback function failed!\n", SNS_NAME);
        return s32Ret;
    }

    CAMERA_CtxExit(dev);

    return EI_SUCCESS;
}

static EI_S32 CAMERA_RegisterIspCallback(VISS_DEV Dev, ISP_DEV dev, ISP_3ALIB_S *pstAeLib, ISP_3ALIB_S *pstAwbLib)
{
    EI_S32 s32Ret;
    AE_SENSOR_REGISTER_S  stAeRegister;
    AWB_SENSOR_REGISTER_S stAwbRegister;

    CAMERA_CHECK_POINTER(pstAeLib);
    CAMERA_CHECK_POINTER(pstAwbLib);

    SNS_SET_ISP_TO_VISS(dev, Dev);

    stAeRegister.SnsId = SNS_ID;
    stAwbRegister.SnsId = SNS_ID;

    s32Ret  = CAMERA_InitAeExpFunction(&stAeRegister.stSnsExp);
    s32Ret |= EI_MI_AE_SensorRegCallBack(dev, pstAeLib, &stAeRegister);

    if (EI_SUCCESS != s32Ret) {
        EI_TRACE_ISP(EI_DBG_ERR, "%s register callback function to ae lib failed!\n", SNS_NAME);
        return s32Ret;
    }

    s32Ret  = CAMERA_InitAwbExpFunction(&stAwbRegister.stSnsExp);
    s32Ret |= EI_MI_AWB_SensorRegCallBack(dev, pstAwbLib, &stAwbRegister);

    if (EI_SUCCESS != s32Ret) {
        EI_TRACE_ISP(EI_DBG_ERR, "%s register callback function to awb lib failed!\n", SNS_NAME);
        return s32Ret;
    }

    return EI_SUCCESS;
}

static EI_S32 CAMERA_UnregisterIspCallback(ISP_DEV dev, ISP_3ALIB_S *pstAeLib, ISP_3ALIB_S *pstAwbLib)
{
    EI_S32 s32Ret;

    CAMERA_CHECK_POINTER(pstAeLib);
    CAMERA_CHECK_POINTER(pstAwbLib);

    s32Ret = EI_MI_AE_SensorUnRegCallBack(dev, pstAeLib, SNS_ID);
    if (EI_SUCCESS != s32Ret) {
        EI_TRACE_ISP(EI_DBG_ERR, "%s unregister callback function to ae lib failed!\n", SNS_NAME);
        return s32Ret;
    }

    s32Ret = EI_MI_AWB_SensorUnRegCallBack(dev, pstAwbLib, SNS_ID);
    if (EI_SUCCESS != s32Ret) {
        EI_TRACE_ISP(EI_DBG_ERR, "%s unregister callback function to awb lib failed!\n", SNS_NAME);
        return s32Ret;
    }

    return EI_SUCCESS;
}

static EI_S32 CAMERA_GetVissDevAttrBySns(SNS_TYPE_E enType,
    VISS_DEV_ATTR_S *pstVissDevAttr)
{
    EI_U32 i;
    const SNS_TYPE_ATTR_S *pstSnsType;

    for (i = 0; i < ARRAY_SIZE(s_astSnsAttr); i++) {
        if (enType == s_astSnsAttr[i].enSnsType) {
            pstSnsType = &s_astSnsAttr[i];
            pstVissDevAttr->stSize          = pstSnsType->stSize;
            pstVissDevAttr->enWorkMode      = pstSnsType->enWorkMode;
            pstVissDevAttr->mClock          = pstSnsType->u32Mclock;
            pstVissDevAttr->enPixelFormat   = pstSnsType->enPixelFormat;
            pstVissDevAttr->enWdrMode       = pstSnsType->enWdrMode;
            pstVissDevAttr->enIspWdrMode    = pstSnsType->enIspWdrMode;
            pstVissDevAttr->enRgbSeq        = pstSnsType->enRgbSeq;
            pstVissDevAttr->u32ModuleClk    = pstSnsType->u32ModuleClk;
            pstVissDevAttr->u32Fps          = pstSnsType->u32FrameRate;
            pstVissDevAttr->u32IspClk       = pstSnsType->u32IspClk;
            pstVissDevAttr->u32IppuClk      = pstSnsType->u32IppuClk;
            pstVissDevAttr->pcSnsName       = SNS_NAME;
            pstVissDevAttr->stDevCfg        = pstSnsType->stDevCfg;
            return EI_SUCCESS;
        }
    }

    PRT_VISS_INFO("%s does not support this dev configuration", SNS_NAME);

    return EI_FAILURE;
}

static EI_S32 CAMERA_GetVissChnAttrBySns(SNS_TYPE_E enType,
    VISS_CHN_ATTR_S *pstVissChnAttr)
{
    EI_U32 i;
    const SNS_TYPE_ATTR_S *pstSnsType;

    for (i = 0; i < ARRAY_SIZE(s_astSnsAttr); i++) {
        if (enType == s_astSnsAttr[i].enSnsType) {
            pstSnsType = &s_astSnsAttr[i];
            pstVissChnAttr->stSize          = pstSnsType->stSize;
            pstVissChnAttr->enPixelFormat   = pstSnsType->enPixelFormat;
            pstVissChnAttr->stFrameRate.s32SrcFrameRate     = pstSnsType->u32FrameRate;
            return EI_SUCCESS;
        }
    }

    PRT_VISS_INFO("%s does not support this chn configuration", SNS_NAME);

    return EI_FAILURE;

}

CAMERA_OBJ_S stCameraOs05a20mipiObj = {
    .pfnRegisterVissCallback    = CAMERA_RegisterVissCallback,
    .pfnUnRegisterVissCallback  = CAMERA_UnregisterVissCallback,
    .pfnRegisterIspCallback     = CAMERA_RegisterIspCallback,
    .pfnUnRegisterIspCallback   = CAMERA_UnregisterIspCallback,
    .pfnGetVissDevAttrBySns     = CAMERA_GetVissDevAttrBySns,
    .pfnGetVissChnAttrBySns     = CAMERA_GetVissChnAttrBySns,
};

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */

